﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Web.UI;
using System.Drawing.Design;
using System.Drawing;
using System.Security.Permissions;

namespace Beetle.Web.UI.WebControls
{
    [ToolboxBitmap(typeof(System.Web.UI.WebControls.Button))]
    [SupportsEventValidation]
    //  [Designer("System.Web.UI.Design.WebControls.ButtonDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
    [DefaultEvent("Click")]
    [ToolboxData("<{0}:Button runat=\"server\" Text=\"Button\"></{0}:Button>")]
    [DataBindingHandler("System.Web.UI.Design.TextDataBindingHandler, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    [ContentPresenterControl("Text")]
    public class Button : System.Web.UI.WebControls.CompositeControl, IButtonControl, IPostBackEventHandler
    {
        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                return HtmlTextWriterTag.Button;
            }
        }

        #region IButtonControl Members


        /// <summary>
        ///  获取或设置在 Button 控件回发到服务器时要进行验证的控件组。
        /// </summary>
        [Category("Behavior")]
        [Description("获取或设置在 Button 控件回发到服务器时要进行验证的控件组。")]
        [Browsable(true)]
        [NotifyParentProperty(true)]
        [DefaultValue(false)]
        [Themeable(true)]
        public bool CausesValidation
        {
            get
            {
                object o = ViewState["CausesValidation"];
                return o != null ? (bool)o : false;
            }

            set
            {
                ViewState["CausesValidation"] = value;
            }
        }
        // Fields
        private static readonly object EventClick = new object();
        private static readonly object EventCommand = new object();

        // Events
        [Category("Action"), Description("Button_OnClick")]
        public event EventHandler Click
        {
            add
            {
                base.Events.AddHandler(EventClick, value);
            }
            remove
            {
                base.Events.RemoveHandler(EventClick, value);
            }
        }

        [Category("Action"), Description("Button_OnCommand")]
        public event CommandEventHandler Command
        {
            add
            {
                base.Events.AddHandler(EventCommand, value);
            }
            remove
            {
                base.Events.RemoveHandler(EventCommand, value);
            }
        }

        /// <summary>
        ///  获取或设置可选参数，该参数与关联的 CommandName 一起被传递到 Command 事件。
        /// </summary>
        [Category("Behavior")]
        [Description("获取或设置可选参数，该参数与关联的 CommandName 一起被传递到 Command 事件。")]
        [Browsable(true)]
        [NotifyParentProperty(true)]
        [DefaultValue("")]
        [Themeable(false)]
        public string CommandArgument
        {
            get
            {
                object o = ViewState["CommandArgument"];
                return o != null ? (string)o : string.Empty;
            }

            set
            {
                ViewState["CommandArgument"] = value;
            }
        }

        /// <summary>
        /// 获取或设置命令名，该命令名与传递给 Command 事件的 Button 控件相关联。 
        /// </summary>
        [Category("Behavior")]
        [Description("获取或设置命令名，该命令名与传递给 Command 事件的 Button 控件相关联。 ")]
        [Browsable(true)]
        [NotifyParentProperty(true)]
        [DefaultValue("")]
        public string CommandName
        {
            get
            {
                object o = ViewState["CommandName"];
                return o != null ? (string)o : string.Empty;
            }

            set
            {
                ViewState["CommandName"] = value;
            }
        }

        /// <summary>
        ///  获取或设置单击 Button 控件时从当前页发送到的网页的 URL。
        /// </summary>
        [Category("Behavior")]
        [Description("获取或设置单击 Button 控件时从当前页发送到的网页的 URL。")]
        [Browsable(true)]
        [NotifyParentProperty(true)]
        [DefaultValue("")]
        [Themeable(false)]
        [UrlProperty("*.aspx")]
        [Editor("System.Web.UI.Design.UrlEditor, System.Design", typeof(UITypeEditor))]
        public string PostBackUrl
        {
            get
            {
                object o = ViewState["PostBackUrl"];
                return o != null ? (string)o : string.Empty;
            }

            set
            {
                ViewState["PostBackUrl"] = value;
            }
        }

        /// <summary>
        /// 获取或设置在 Button 控件中显示的文本标题。 
        /// </summary>
        [Category("Appearance")]
        [Description("获取或设置在 Button 控件中显示的文本标题。 ")]
        [Browsable(true)]
        [NotifyParentProperty(true)]
        [DefaultValue("")]
        [Localizable(true)]
        [Bindable(true)]
        public string Text
        {
            get
            {
                object o = ViewState["Text"];
                return o != null ? (string)o : string.Empty;
            }

            set
            {
                ViewState["Text"] = value;
                this.ChildControlsCreated = false;
            }
        }

        [Themeable(false), Description("Button_OnClientClick"), DefaultValue(""), Category("Behavior")]
        public virtual string OnClientClick
        {
            get
            {
                string str = (string)this.ViewState["OnClientClick"];
                if (str == null)
                {
                    return string.Empty;
                }
                return str;
            }
            set
            {
                this.ViewState["OnClientClick"] = value;
            }
        }


        /// <summary>
        ///  获取或设置在 Button 控件回发到服务器时要进行验证的控件组。
        /// </summary>
        [Category("Behavior")]
        [Description("获取或设置在 Button 控件回发到服务器时要进行验证的控件组。")]
        [Browsable(true)]
        [NotifyParentProperty(true)]
        [Themeable(false)]
        [DefaultValue("")]
        public string ValidationGroup
        {
            get
            {
                object o = ViewState["ValidationGroup"];
                return o != null ? (string)o : string.Empty;
            }

            set
            {
                ViewState["ValidationGroup"] = value;
            }
        }
        #endregion

        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            if (this.Page != null)
            {
                this.Page.VerifyRenderingInServerForm(this);
            }


            writer.AddAttribute(HtmlTextWriterAttribute.Type, "button");

            PostBackOptions postBackOptions = this.GetPostBackOptions();
            string uniqueID = this.UniqueID;
            if ((uniqueID != null) && ((postBackOptions == null) || (postBackOptions.TargetControl == this)))
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Name, uniqueID);
            }
            writer.AddAttribute(HtmlTextWriterAttribute.Value, this.Text);
            bool isEnabled = base.IsEnabled;
            string firstScript = string.Empty;
            if (isEnabled)
            {
                firstScript = Helper.EnsureEndWithSemiColon(this.OnClientClick);
                if (base.HasAttributes)
                {
                    string str3 = base.Attributes["onclick"];
                    if (str3 != null)
                    {
                        firstScript = firstScript + Helper.EnsureEndWithSemiColon(str3);
                        base.Attributes.Remove("onclick");
                    }
                }
                if (this.Page != null)
                {
                    string postBackEventReference = this.Page.ClientScript.GetPostBackEventReference(postBackOptions, false);
                    if (postBackEventReference != null)
                    {
                        firstScript = Helper.MergeScript(firstScript, postBackEventReference);
                    }
                }
            }
            if (this.Page != null)
            {
                this.Page.ClientScript.RegisterForEventValidation(postBackOptions);
            }
            if (firstScript.Length > 0)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Onclick, firstScript);
                writer.AddAttribute("language", "javascript", false);
            }

            if (this.Enabled && !isEnabled)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled");
            }

            base.AddAttributesToRender(writer);
        }

        protected virtual PostBackOptions GetPostBackOptions()
        {
            PostBackOptions options = new PostBackOptions(this, string.Empty);
            options.ClientSubmit = false;
            if (this.Page != null)
            {
                if (this.CausesValidation && (this.Page.GetValidators(this.ValidationGroup).Count > 0))
                {
                    options.PerformValidation = true;
                    options.ValidationGroup = this.ValidationGroup;
                }
                if (!string.IsNullOrEmpty(this.PostBackUrl))
                {
                    options.ActionUrl = HttpUtility.UrlPathEncode(base.ResolveClientUrl(this.PostBackUrl));
                }

                options.ClientSubmit = true;
            }

            return options;
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            if ((this.Page != null) && base.IsEnabled)
            {
                if ((this.CausesValidation && (this.Page.GetValidators(this.ValidationGroup).Count > 0)) || !string.IsNullOrEmpty(this.PostBackUrl))
                {
                    Helper.RegisterWebFormsScript(this.Page);
                }
                else
                {
                    Helper.RegisterPostBackScript(this.Page);
                }
            }
        }

        private ITemplate contentTemplate = null;
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate ContentTemplate
        {
            get
            {
                return this.contentTemplate;
            }
            set
            {
                this.contentTemplate = value;
                this.ChildControlsCreated = false;
            }
        }

        public Button()
        {
        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            this.Controls.Clear();

            if (this.ContentTemplate != null)
            {
                this.ContentTemplate.InstantiateIn(this);
            }
            else
            {
                this.Controls.Add(new LiteralControl(this.Text));
            }

            this.ChildControlsCreated = true;
        }

        protected virtual void OnClick(EventArgs e)
        {
            EventHandler handler = (EventHandler)base.Events[EventClick];
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected virtual void OnCommand(CommandEventArgs e)
        {
            CommandEventHandler handler = (CommandEventHandler)base.Events[EventCommand];
            if (handler != null)
            {
                handler(this, e);
            }
            base.RaiseBubbleEvent(this, e);
        }

        #region IPostBackEventHandler 成员

        public void RaisePostBackEvent(string eventArgument)
        {
            this.Page.ClientScript.ValidateEvent(this.UniqueID, eventArgument);

            if (this.CausesValidation)
            {
                this.Page.Validate(this.ValidationGroup);
            }

            this.OnClick(EventArgs.Empty);
            this.OnCommand(new CommandEventArgs(this.CommandName, this.CommandArgument));
        }

        #endregion
    }
}
